<?php
declare(strict_types=1);
defined('MI7') or exit('No direct script access allowed');

require BASEPATH . '/config/config.php';
require BASEPATH . '/config/database.php';
require BASEPATH . '/config/route.php';

//require BASEPATH . '/core/error.php';

use Swow\Coroutine;
use Swow\CoroutineException;
use Swow\Errno;
use Swow\Http\Protocol\ProtocolException as HttpProtocolException;
use Swow\Http\Status as HttpStatus;
use Swow\Psr7\Psr7;
use Swow\Psr7\Server\Server;
use Swow\Socket;
use Swow\SocketException;


use mi7soft\core\Main;
use mi7soft\core\Config;
use mi7soft\core\Context;

use mi7soft\system\controller\user;

ini_set('memory_limit', '1G');


/**
 * 初始化config
 */

/**
 * 初始化日志
 */

/**
 * 开启服务
 */
$host = $_ENV['SERVER_HOST'] ?: '127.0.0.1';
$port = (int)((($port = $_ENV['SERVER_PORT']) !== '' && $port !== false) ? $port : 80);

$backlog = (int)(getenv('SERVER_BACKLOG') ?: Socket::DEFAULT_BACKLOG);


$server = new Server();
$server->bind($host, $port)->listen($backlog);

while (true) {
    try {
        $connection = $server->acceptConnection();
        Coroutine::run(static function () use ($connection): void {
            try {
                while (true) {
                    try {
                        $request = $connection->recvHttpRequest();
//                        print_r($request->getMethod());
//                        print_r($request->getQueryParams());
//                        print_r($request->getParsedBody());
                        switch ($request->getUri()->getPath()) {
                            case '/greeter':
                                $connection->respond(sprintf('Hello %s', Swow::class, $connection->getProtocolType()));
                                break;
                            case '/echo':
                                echo microtime(true);
                                echo config::get_int("sub_directory");
                                $connection->respond($request->getBody());
                                break;
                            case '/echo_all':
                                $connection->respond(Psr7::stringifyRequest($request));
                                break;
                            default:
                                echo "#################################################\n";
                                echo $request->getUri()->getPath() . "\n";
                                $content = (new Main())->run();
                                $connection->respond($content->starttime . ' ' . $content->endtime . ' ' . ($content->endtime - $content->starttime));
//                                $connection->error(HttpStatus::NOT_FOUND);
                                break;
                        }
                    } catch (HttpProtocolException $exception) {
                        $connection->error($exception->getCode(), $exception->getMessage(), close: true);
                        break;
                    }
                    if (!$connection->shouldKeepAlive()) {
                        break;
                    }
                }
            } catch (Exception) {
                // you can log error here
            } finally {
                $connection->close();
            }

        });


    } catch (SocketException|CoroutineException $exception) {
        if (in_array($exception->getCode(), [Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM], true)) {
            sleep(1);
        } else {
            break;
        }
    }
}